#include "Restricoes.h"


void Restricoes::calcular()
{
    #pragma omp single
    {
        for (SPHERE* s = pModel->SPHList.Begin; s != NULL; s = s->Next)
        {
            if (s->Constraint == SPHERE::STATIC) s->F[0] = s->F[1] = s->F[2] = 0.0;
            else if (s->Constraint == SPHERE::SOCKET) s->F[0] = s->F[1] = 0.0;

            /*if (s->IsSensor) {
                fprintf( pModel->SensorOut, "%li\t% .7e\t% .7e\t% .7e\t% .7e\t% .7e\n", s->Index, pModel->Time, s->R[0], s->R[1], s->Fs[0], s->Fs[1] );
                s->Fs[0] = s->Fs[1] = 0.0;
            }*/
        }
    }
    #pragma omp barrier
}

RestricoesParalelo::RestricoesParalelo(MODEL*md)
{
    pModel=md;
    numSockets=numStatics=0;
    //Itero na lista de todas as esferas e conto cada elemento estático e socket
    for (SPHERE* s = pModel->SPHList.Begin; s != NULL; s = s->Next)
    {
        if (s->Constraint == SPHERE::STATIC) numStatics++;
        else if (s->Constraint == SPHERE::SOCKET) numSockets++;
    }
    cout << "Número de Sockets: " << numSockets << '\n';
    cout << "Número de Estáticos: " << numStatics << '\n';
    //Aloco espaço para eles nos dois vetores
    sockets=new SPHERE*[numSockets];
    statics=new SPHERE*[numStatics];
    int contSock=0;
    int contSta=0;
    //Com eles contados, posso inserí-los em seus respectivos vetores
    for (SPHERE* s = pModel->SPHList.Begin; s != NULL; s = s->Next)
    {
        if (s->Constraint == SPHERE::STATIC)
        {
            statics[contSta]=s;
            contSta++;
        }
        else if (s->Constraint == SPHERE::SOCKET)
        {
            sockets[contSock]=s;
            contSock++;
        }
    }
}
void RestricoesParalelo::calcular()
{
    // A cada passo percorro a lista e zero a contribuição dos dois
    #pragma omp for schedule (dynamic,1) nowait
    for (int i = 0; i < numStatics; i++)
    {
        statics[i]->F[0] = 0.0;
        statics[i]->F[1] = 0.0;
        statics[i]->F[2] = 0.0;
    }
    //sem barreira
    #pragma omp for schedule (dynamic,1)
    for (int j = 0; j < numSockets ; j++)
    {
        sockets[j]->F[0] = 0.0;
        sockets[j]->F[1] = 0.0;
    }
    //barreira implícita

    /*
    #pragma omp for schedule (dynamic,1)
    for (int i = 0; i < pModel->numProceEsf; i++)
    {
        SPHERE* testeFim;
        if (i!=pModel->numProceEsf-1) testeFim = pModel->threads[i+1];
        else testeFim=NULL;

        for (SPHERE* s = pModel->threads[i]; s != testeFim; s = s->Next)
        {
            if (s->Constraint == SPHERE::STATIC) s->F[0] = s->F[1] = s->F[2] = 0.0;
            else if (s->Constraint == SPHERE::SOCKET) s->F[0] = s->F[1] = 0.0;

        }
    }
    */
}
